mod errors;
mod article;
mod models;
mod user;
mod comment;

use errors::CustomError;
use ntex::web::{self, middleware, App, HttpServer};
use article::api;
use sqlx::{Pool, Sqlite, SqlitePool};

#[derive(Debug, Clone)]
pub struct AppState {
    pub db_pool: Pool<Sqlite>,
}

#[ntex::main]
async fn main() {
    dotenvy::dotenv().ok();

    std::env::set_var("RuST_LOG", "ntex=info");
    env_logger::init();

    let database_url = std::env::var("DATABASE_URL").expect("missing DATABASE_URL");
    let app_state = std::sync::Arc::new(AppState {
        db_pool: SqlitePool::connect(&database_url)
            .await.expect("can't connect to database"),
    });


    println!("Server is running at http://127.0.0.1:8000");
    HttpServer::new(move || {
        App::new()
            .state(std::sync::Arc::clone(&app_state))
            .wrap(middleware::Logger::default())
            .service(index) //测试路由
            .service(error) //测试错误处理
            .service(api::get_articles_preview) // //articles_preview 获取文章预览
            .service(api::get_article)          // /articles 获取单个文章
            .service(api::new_article)          // /new_article 新增文章
            .service(api::update_article)       // /update_article 更新文章
            .service(api::delete_article)       // /delete_article 删除文章
            .configure(route)   // 不使用宏 配置路由
            
    })
    .bind("127.0.0.1:8000")
    .unwrap()
    .run()
    .await
    .unwrap();

}

fn route(cfg: &mut web::ServiceConfig)
{
    cfg
        .service(web::scope("/articles") // 配置路由前缀
            .route("/search/{keyword}", web::get().to(api::serach_article))
        )
        .service(web::scope("/user")
            .route("/login",web::post().to(user::login::github_login))
        )
        .service(web::scope("/comment")
            .route("/get/{article_id}",web::get().to(comment::api::get_comments_for_article_id))
            .route("/add", web::post().to(comment::api::add_comment))
            .route("/delete/{comment_id}", web::delete().to(comment::api::delete_comment))
        );
}

#[web::get("/")]
async fn index() -> &'static str { //返回值需要实现ntex::web::HttpResponse
    "Hello from ntex-yew!"
}

#[web::get("/error")]
async fn error() -> Result<String, CustomError> {
    Err(CustomError::NotFound("not found".into()))
}
